#region Summary 

// 
// Owner : JackieHan 
// 
// Solution : LearnSolution 
// 
// Project : JackieHan.DotNet.ExtensionMethods 
// 
// File : KeyEqualityComparer.cs 
// 
// CopyRight : Copyright © 2009-2010 JackieHan Personal, All Rights Reserved 
// 
// Summary : 比较接口 
// 
// History : 
//			2010-05-19 16:11:26	    Create 
// 

#endregion

#region Using 

using System;
using System.Collections.Generic;
using System.Linq;

#endregion

namespace JackieHan.DotNet.ExtensionMethods.ExtensionIList
{
    /// <summary> 
    /// 比较接口 
    /// </summary> 
    public class KeyEqualityComparer<T>:IEqualityComparer<T>
    {
        private readonly Func<T, T, bool> comparer;
        private readonly Func<T, object> keyExtractor;

        public KeyEqualityComparer(Func<T,object > keyExtractor):this(keyExtractor,null)
        {

        }

        public KeyEqualityComparer(Func<T,T,bool> comparer):this(null,comparer)
        {
        }

        public KeyEqualityComparer(Func<T,object > keyExtractor,Func<T,T,bool > compare)
        {
            this.keyExtractor = keyExtractor;
            this.comparer = compare;
        }

        public bool Equals(T x, T y)
        {
            if (comparer != null)
                return comparer(x, y);
            else
            {
                var valX = keyExtractor(x);
                if (valX is IEnumerable<object>)
                    return ((IEnumerable<object>) valX).SequenceEqual((IEnumerable<object>) keyExtractor(y));
                return valX.Equals(keyExtractor);
            }
        }

        public int GetHashCode(T obj)
        {
            if (keyExtractor == null)
                return obj.ToString().ToLower().GetHashCode();
            else
            {
                var val = keyExtractor(obj);
                if (val is IEnumerable<object>)
                    return (int) ((IEnumerable<object>) val).Aggregate((x, y) => x.GetHashCode() ^ y.GetHashCode());
                return val.GetHashCode();
            }
        }
    }
}
